#include <string>
#include "DX.h"

DX::DX( ) : backBuffer( 0 ), direct3D( 0 ), device( 0 ), monitor( 0 ) 
{
	direct3D = Direct3DCreate9( D3D_SDK_VERSION );
}

DX* DX::_() 
{
	return ( inst ) ? inst : inst = new DX;
}

DX* DX::inst = 0;

HRESULT DX::init( HWND hWnd, bool windowed )
{	
	_hWnd = hWnd;
	
	//direct3D = Direct3DCreate9( D3D_SDK_VERSION );

	direct3D->GetAdapterDisplayMode( monitor, &d3ddm );

	ZeroMemory( &d3dpp, sizeof( d3dpp ) );

	d3dpp.Windowed = windowed;
	
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	d3dpp.BackBufferFormat = d3ddm.Format;
	d3dpp.BackBufferCount = 1;
	
	d3dpp.EnableAutoDepthStencil = TRUE;
	d3dpp.AutoDepthStencilFormat = D3DFMT_D24X8;

	if ( d3dpp.Windowed )
	{
		RECT clrect;
		GetClientRect( hWnd, &clrect );
		d3dpp.BackBufferWidth =		clrect.right - clrect.left;
		d3dpp.BackBufferHeight =	clrect.bottom - clrect.top;
	}
	else
	{
		d3dpp.BackBufferWidth =		d3ddm.Width;
		d3dpp.BackBufferHeight =	d3ddm.Height;
	}

	d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
	d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;

	if ( !d3dpp.Windowed )
		d3dpp.FullScreen_RefreshRateInHz = d3ddm.RefreshRate;
	
	direct3D->CreateDevice( monitor, D3DDEVTYPE_HAL, hWnd, /*D3DCREATE_PUREDEVICE |*/ D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, &d3dpp, &device );
	
	if ( !device )
	{
		d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
		direct3D->CreateDevice( monitor, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, &d3dpp, &device );
		if ( !device )
		{
			direct3D->CreateDevice( monitor, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, &d3dpp, &device );
			if ( !device )
			{
				throw std::wstring( TEXT( "DX : CreateDevice failed" ) );
			}
		}
	}
	
	HRESULT hr = device->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &backBuffer );
	device->SetRenderTarget( 0, backBuffer );
	
	device->SetRenderState( D3DRS_ZENABLE, D3DZB_FALSE );
	device->SetRenderState( D3DRS_LIGHTING, FALSE );

	//dx()->device->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
	//dx()->device->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );

	return hr;
}

DX::~DX( void )
{
	if ( backBuffer ) backBuffer->Release();
	if ( device ) device->Release();
	if ( direct3D ) direct3D->Release();
	inst = 0;
}
